home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 1.iso / toolbox / src / tutorials / custEducation / opengl2 / examples / porting / xsolar_irisgl.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-11-11  |  10.0 KB  |  403 lines

  1. /*                xsolar_irisgl.c
  2.  *    Displays a planet with a moon, orbiting a sun.
  3.  *     Uses X and IRIS GL widget.
  4.  *
  5.  *    Exit with the ESCape key or through the window manager menu.
  6.  */
  7. #include <Xm/Xm.h>
  8. #include <Xm/Frame.h>
  9. #include <Xm/Form.h>
  10. #include <X11/Xirisw/GlxMDraw.h>
  11. #include <X11/StringDefs.h>
  12. #include <X11/keysym.h>
  13.  
  14. #include <gl/gl.h>
  15. #include <gl/device.h>
  16. #include <gl/get.h>
  17. #include <stdio.h>
  18. #include <math.h>
  19.  
  20. typedef struct _spin {
  21.     short year;
  22. } SPINDATA, *SPINPTR;
  23.  
  24. /* function prototypes */
  25.  
  26. void main(int argc, char **argv);
  27.  
  28. void initCB (Widget w, XtPointer client_data, XtPointer call_data);
  29. void exposeCB (Widget w, XtPointer spin, XtPointer call_data);
  30. void resizeCB (Widget w, XtPointer spin, XtPointer call_data);
  31. void inputCB (Widget w, XtPointer client_data, XtPointer call_data);
  32.  
  33. Boolean drawWP (XtPointer spin);
  34.  
  35. void drawscene(SPINPTR spin);
  36. void setbeachball(int stripes);
  37. void beachball(unsigned long color1, unsigned long color2);
  38.  
  39. SPINPTR spin;
  40.  
  41. static XtAppContext app_context;
  42. static XtWorkProcId workprocid = NULL;
  43.  
  44. /* Create application context, and a form widget to contain
  45.  * the IRIS GL widget.  Set up the IRIS GL widget callbacks
  46.  */
  47. void main(int argc, char **argv)
  48. {
  49.     Arg wargs[15];
  50.     int n;
  51.     Widget glw, toplevel, frame, form;
  52.  
  53.     static GLXconfig glxConfig [] = {
  54.         {GLX_NORMAL, GLX_DOUBLE, TRUE},
  55.         {GLX_NORMAL, GLX_RGB, TRUE},
  56.         {GLX_NORMAL, GLX_ZSIZE, GLX_NOCONFIG},
  57.         {0, 0, 0}
  58.     };    
  59.  
  60.     static String fallback_resources[] = {
  61.         "*frame*shadowType: SHADOW_IN",
  62.         "*glwidget*width: 750",
  63.         "*glwidget*height: 600",
  64.         NULL
  65.     };
  66.  
  67.     /*    create main data structure, spin pointer    */
  68.     spin = (SPINPTR) malloc (sizeof (SPINDATA));
  69.     spin->year = 0;
  70.  
  71.     toplevel = XtAppInitialize(
  72.             &app_context,    /* Application context */
  73.             "XSolar",    /* Application class */
  74.             NULL, 0,     /* command line option list */
  75.             &argc, argv,    /* command line args */
  76.             fallback_resources,
  77.             NULL,        /*  argument list  */
  78.             0);        /* number of arguments */
  79.  
  80.     n = 0;
  81.     form = XmCreateForm(toplevel, "form", wargs, n);
  82.     XtManageChild(form);
  83.  
  84.     n = 0;
  85.     XtSetArg(wargs[n], XtNx, 30); n++;
  86.     XtSetArg(wargs[n], XtNy, 30); n++;
  87.     XtSetArg(wargs[n], XmNbottomAttachment, XmATTACH_FORM); n++;
  88.     XtSetArg(wargs[n], XmNleftAttachment, XmATTACH_FORM); n++;
  89.     XtSetArg(wargs[n], XmNrightAttachment, XmATTACH_FORM); n++;
  90.     XtSetArg(wargs[n], XmNtopAttachment, XmATTACH_FORM); n++;
  91.  
  92.     XtSetArg(wargs[n], XmNleftOffset, 30); n++;
  93.     XtSetArg(wargs[n], XmNbottomOffset, 30); n++;
  94.     XtSetArg(wargs[n], XmNrightOffset, 30); n++;
  95.     XtSetArg(wargs[n], XmNtopOffset, 30); n++;
  96.     frame = XmCreateFrame (form, "frame", wargs, n);
  97.     XtManageChild (frame);
  98.  
  99.     n = 0;
  100.     XtSetArg(wargs[n], GlxNglxConfig, glxConfig); n++;
  101.     glw = GlxCreateMDraw(frame, "glwidget", wargs, n);
  102.     XtManageChild (glw);
  103.     XtAddCallback(glw, GlxNginitCallback, initCB, 
  104.         (XtPointer) NULL);
  105.     XtAddCallback(glw, GlxNexposeCallback, exposeCB, 
  106.         (XtPointer) spin);
  107.     XtAddCallback(glw, GlxNresizeCallback, resizeCB, 
  108.         (XtPointer) spin);
  109.     XtAddCallback(glw, GlxNinputCallback, inputCB, 
  110.         (XtPointer) NULL);
  111.  
  112.     workprocid = XtAppAddWorkProc (app_context, drawWP, 
  113.         (XtPointer) spin);
  114.  
  115.     XtRealizeWidget(toplevel);    /* instantiate it now */
  116.     XtAppMainLoop(app_context);    /* loop for events */
  117. }    /*   end main()   */
  118.  
  119. /*        initCB     
  120.  *    The initCB subroutine initializes graphics modes and
  121.  *    transformation matrices.
  122.  */
  123.  
  124. void initCB (Widget w, XtPointer client_data, XtPointer call_data)
  125. {
  126.     long gid1, xmax, ymax;
  127.     float aspect;
  128.  
  129.     GLXwinset(XtDisplay(w), XtWindow(w));
  130.  
  131.     xmax = getgdesc(GD_XPMAX);
  132.     ymax = getgdesc(GD_YPMAX);
  133.     if (getgdesc(GD_BITS_NORM_ZBUFFER) == 0)
  134.     {
  135.         fprintf(stderr, 
  136.             "This machine does not have a hardware zbuffer\n");
  137.         exit(0);
  138.     }
  139.  
  140.     zbuffer(TRUE);
  141.     shademodel(FLAT);
  142.  
  143.     qdevice(LEFTMOUSE);
  144.     qdevice(MIDDLEMOUSE);
  145.     qdevice(ESCKEY);
  146.     tie(LEFTMOUSE, MOUSEX, MOUSEY);
  147.  
  148.     /* separtae ModelView and Projection matrix stacks;
  149.      * both are initialized with an identity matrix.
  150.      */
  151.     mmode(MVIEWING);
  152.     aspect = (float) xmax / (float) ymax;
  153.  
  154.     /* projection commands replace projection matrix */
  155.     perspective(450, aspect, 1.0, 25.0);
  156.  
  157.     /* viewing commands premultiply the ModelView matrix */
  158.     polarview(12.0, 0, -100, 0);
  159. }    /*   end initCB()   */
  160.  
  161. /*    exposeCB() and resizeCB() are called when the window
  162.  *    is uncovered, moved, or resized.
  163.  */
  164.  
  165. void exposeCB (Widget w, XtPointer ptr, XtPointer call_data)
  166. {
  167.     SPINPTR spin;
  168.  
  169.     spin = (SPINPTR) ptr;
  170.     GLXwinset (XtDisplay(w), XtWindow(w));
  171.     drawscene(spin);
  172. }
  173.  
  174. void resizeCB (Widget w, XtPointer ptr, XtPointer call_data)
  175. {
  176.     GlxDrawCallbackStruct *call_ptr;
  177.     SPINPTR spin;
  178.  
  179.     spin = (SPINPTR) ptr;
  180.     call_ptr = (GlxDrawCallbackStruct *) call_data;
  181.     GLXwinset (XtDisplay(w), XtWindow(w));
  182.     viewport (0, (Screencoord) call_ptr->width-1,
  183.         0, (Screencoord) call_ptr->height-1);
  184.     drawscene(spin);
  185. }
  186.  
  187. /*    inputCB() handles all types of input from the GL widget.
  188.  *    The KeyRelease handles the ESCape key, so that it exits
  189.  *    the program.  
  190.  */
  191. void inputCB (Widget w, XtPointer client_data, 
  192.     XtPointer call_data)
  193. {
  194.     char buffer[1];
  195.     KeySym keysym;
  196.     GlxDrawCallbackStruct *call_ptr = 
  197.                 (GlxDrawCallbackStruct *) call_data;
  198.     XKeyEvent *kevent = (XKeyEvent *) (call_ptr->event);
  199.  
  200.     switch(call_ptr->event->type) {
  201.     case KeyRelease:
  202.         /* It is necessary to convert the keycode to a 
  203.          * keysym before checking if it is an escape */
  204.         if (XLookupString(kevent,buffer,1,&keysym,NULL) == 1 
  205.             && keysym == (KeySym)XK_Escape)
  206.             exit(0);
  207.         break;
  208.     default:
  209.         break;
  210.     }
  211. }
  212.  
  213. /*    drawWP() is called by the WorkProc.  When the scene
  214.  *    is in automatic motion, the WorkProc calls this routine,
  215.  *    which adds 1 degree (10 tenths) to the cumulative amount
  216.  *    of rotation.  drawscene() is called, so the image is
  217.  *    redrawn.  It returns(FALSE) so the WorkProc does not
  218.  *    discontinue operation.
  219.  */
  220. Boolean drawWP (XtPointer ptr)
  221. {
  222.     SPINPTR spin;
  223.  
  224.     spin = (SPINPTR) ptr;
  225.     spin->year = (spin->year + 10) % 3600;
  226.     drawscene (spin);
  227.     return (FALSE);
  228. }
  229.  
  230.  
  231. /*    drawscene calculates angles relative to the spin->year
  232.  *    and then draws sun, planet, and moon.
  233.  */
  234.  
  235. void drawscene(SPINPTR spin)
  236. {
  237.     static long blackcol[] = { 0, 0, 0 };
  238.     static long bluecol[] = { 0, 0, 255 };
  239.     static long whitecol[] = { 255, 255, 255 };
  240.     short sunangle, dayangle, monthangle;
  241.     /* actual 1.5e8 kM * 3.0e-9 fudgefactor */
  242.     float earthdist = 4.5, earthscale = 0.5;
  243.     float moondist = 0.9, moonscale = 0.2;
  244.  
  245.     c3i(blackcol);
  246.     /* clear color & z buffers */
  247.     czclear(getgdesc(GD_ZMIN),getgdesc(GD_ZMAX)); 
  248.     pushmatrix();
  249.     sunangle = (spin->year*365/25) % 3600;
  250.     /* sun rotates on axis every 25 days */
  251.     rotate(sunangle, 'y');
  252.     beachball(0x20C0FF, 0x200FFFF); /* colors in cpack format */
  253.     popmatrix();
  254.     pushmatrix();
  255.     rotate(spin->year, 'y');
  256.     translate(earthdist, 0.0, 0.0);
  257.     pushmatrix();
  258.     dayangle = (spin->year*50) % 3600; /* fudged */
  259.     rotate(dayangle, 'y');
  260.     scale(earthscale, earthscale, earthscale);
  261.     c3i(bluecol);
  262.     beachball(0xFF0000, 0xC02000); /* earth */
  263.     popmatrix();
  264.     monthangle = (spin->year*365/28) % 3600;
  265.     rotate(monthangle, 'y');
  266.     translate (moondist, 0.0, 0.0);
  267.     scale(moonscale, moonscale, moonscale);
  268.     c3i(whitecol);
  269.     beachball(0xFFFFFF, 0xC0C0C0); /* moon */
  270.     popmatrix();
  271.  
  272.     swapbuffers();
  273. }   /*  end drawscene()  */
  274.  
  275. /* BEACHBALL */
  276.  
  277. /* three dimensional vector */
  278. typedef float vector[3];
  279.  
  280. static vector front  = { 0.0,  0.0,  1.0 };
  281. static vector back   = { 0.0,  0.0, -1.0 };
  282. static vector top    = { 0.0,  1.0,  0.0 };
  283. static vector bottom = { 0.0, -1.0,  0.0 };
  284. static vector right  = { 1.0,  0.0,  0.0 };
  285. static vector left   = { -1.0,  0.0,  0.0 };
  286. static vector center = { 0.0,  0.0,  0.0 };
  287.  
  288. /* Number of colored stripes. Should be even to look right */
  289. #define BEACHBALL_STRIPES 12
  290.  
  291. /* Default number of polygons  making up a stripe. Should be even */
  292. #define BEACHBALL_POLYS 16
  293.  
  294. /* array of vertices making up a stripe */
  295. static vector stripe_point[BEACHBALL_POLYS + 3];
  296.  
  297. /* has the beachball been initialized */
  298. static Boolean beachball_initialized = FALSE;
  299.  
  300. /* Number of polygons making up a stripe */
  301. static int beachball_stripes;
  302.  
  303. /* Number of vertices making up a stripe */
  304. static int stripe_vertices;
  305.  
  306. /* Initialize beachball_point array to be a stripe 
  307.  * of unit radius.
  308.  */
  309. void setbeachball(int stripes)
  310. {
  311.     int i,j;
  312.     float x,y,z;             /* vertex points */
  313.     float theta,delta_theta;    /* angle from top pole to bottom pole */
  314.     float offset;         /* offset from center of stripe to vertex */
  315.     float cross_radius; /* radius of cross section at current latitude */
  316.     float cross_theta;  /* angle occupied by a stripe  */
  317.  
  318.     beachball_stripes = stripes;
  319.  
  320.     /* polys distributed by even angles from top to bottom */
  321.     delta_theta = M_PI/((float)BEACHBALL_POLYS/2.0);
  322.     theta = delta_theta;
  323.  
  324.     cross_theta = 2.0*M_PI/(float)beachball_stripes;
  325.  
  326.     j = 0;
  327.  
  328.     stripe_point[j][0] = top[0];
  329.     stripe_point[j][1] = top[1];
  330.     stripe_point[j][2] = top[2];
  331.     j++;
  332.  
  333.     for (i = 0; i < BEACHBALL_POLYS; i += 2) {
  334.         cross_radius = fsin(theta);
  335.         offset = cross_radius * ftan(cross_theta/2.0);
  336.  
  337.         stripe_point[j][0] = - offset;
  338.         stripe_point[j][1] = fcos(theta);
  339.         stripe_point[j][2] = cross_radius;
  340.         j++;
  341.  
  342.         stripe_point[j][0] = offset;
  343.         stripe_point[j][1] = stripe_point[j-1][1];
  344.         stripe_point[j][2] = stripe_point[j-1][2];
  345.         j++;
  346.  
  347.         theta += delta_theta;
  348.     }
  349.  
  350.     stripe_point[j][0] = bottom[0];
  351.     stripe_point[j][1] = bottom[1];
  352.     stripe_point[j][2] = bottom[2];
  353.  
  354.     stripe_vertices = j + 1;
  355.  
  356.     beachball_initialized = TRUE;
  357. }
  358.  
  359. /*
  360.  *    Draws a canonical beachball.  The colors are cpack values 
  361.  *    when in RGBmode, colormap indices when in colormap mode.
  362.  */
  363. void beachball(unsigned long c1, unsigned long c2)
  364. {
  365.     long mode;
  366.     float angle, delta_angle;
  367.     int i,j;
  368.  
  369.     if (! beachball_initialized)
  370.         setbeachball(BEACHBALL_STRIPES);
  371.  
  372.     mode = getdisplaymode();
  373.  
  374.     angle = 0.0;
  375.     delta_angle = 360.0/(float)beachball_stripes;
  376.  
  377.     for (i = 0; i < beachball_stripes; i++) {
  378.         switch(mode) {
  379.         case DMSINGLE: case DMDOUBLE:
  380.             if ( i%2 == 0)
  381.                 color(c1);
  382.             else color(c2);
  383.             break;
  384.         case DMRGB: case DMRGBDOUBLE:
  385.             if ( i%2 == 0)
  386.                 cpack(c1);
  387.             else cpack(c2);
  388.             break;
  389.         }
  390.  
  391.         pushmatrix();
  392.         rot(angle, 'y');
  393.         angle += delta_angle;
  394.  
  395.         bgntmesh();
  396.             for (j = 0; j < stripe_vertices; j++)
  397.                 v3f(stripe_point[j]);
  398.         endtmesh();
  399.         popmatrix();
  400.     }
  401. }
  402.  
  403.